![AWS再入門ブログリレー SQS編](https://devio2023-media.developers.io/wp-content/uploads/2019/04/amazon-sqs.png)
AWS再入門ブログリレー SQS編
こんにちは、コンサルティング部 もこ@札幌オフィス です!
当エントリは弊社コンサルティング部による『AWS再入門ブログリレー 2019』の22日目のエントリです。
このブログリレーの企画は、普段AWSサービスについて最新のネタ・深い/細かいテーマを主に書き連ねてきたメンバーの手によって、 今一度初心に返って、基本的な部分を見つめ直してみよう、解説してみようというコンセプトが含まれています。
AWSをこれから学ぼう!という方にとっては文字通りの入門記事として、またすでにAWSを活用されている方にとってもAWSサービスの再発見や2019年のサービスアップデートのキャッチアップの場となればと考えておりますので、ぜひ最後までお付合い頂ければ幸いです。
本日22日目のテーマは『Amazon Simple Queue Service』です。
目次
- 目次
- Amazon Simple Queue Service(SQS)とは?
- 前提知識
- SQSのタイプ
- 標準キュー
- FIFOキュー
- FIFOキューの制限
- SQSのライフサイクル
- SQSを使ってアプリケーションを作ってみた
- (レジ) ハンバーガーの注文を受け付ける
- (厨房) ハンバーガーの注文を処理する
- まとめ
Amazon Simple Queue Service(SQS)とは?
Amazon Simple Queue Service(以下SQS)はフルマネージド型のメッセージキューサービスです。
「メッセージをSQSの送信」、「SQSからメッセージをポーリング」することができ、SQSを利用することによって
- 軽い受付処理をした結果をSQSに登録し、別のサーバーからメッセージをポーリングし、重い処理を済ませる
-
SQS側で処理予定のタスクをバッファーでき、スパイク的なアクセスに耐えれる構成を作成できる
-
SQSに登録されているキューに基づいてSQSをポーリングし、処理を行うサーバーをスケールする事ができる
-
SQSをトリガーにLambdaをキックし、サーバーレスが捗る
などなどで、お店で例えて言うと
「注文はチーズバーガー→お会計130円です→チーズバーガーを作成→チーズバーガーを返す」
ような同期的なアプリケーションを
「レジ側: 注文はチーズバーガー→お会計130円です(SQSにキューを登録)」
「厨房側: SQSをポーリング、チーズバーガーを作成、チーズバーガーを返す」
のように、レジと厨房を非同期で処理できるため、レジでは注文と会計のみの仕事に集中もできますし、何よりチーズバーガーを作る作業は厨房に丸投げするため、お客様にも待たさずに次々と注文を受け付けられます。
また、キューの量をトリガーにスケールすることも可能です。
前提知識
メッセージをSQSに送信するアプリケーションのことを「プロデューサー」と呼び、
SQSからメッセージをポーリングするアプリケーションのことを「コンシューマー」と呼びます。
SQSに送信できる最大サイズは256KBで、SQS側での最長保持期間は14日です。
SQSのタイプ
SQSには2つの種類があり、「標準キュー」、「FIFOキュー」があります。
標準キュー
「順不同な可能性がある」、「複数回配信される可能背がある」、「ほぼ無制限に送信ができる」、標準的なキューです。
(1, 2, 3, 4)->SQS->(2, 4, 1, 3, 4)
のように順不同で配信される可能性があり、同じメッセージを複数回配信される可能性があります。
複数回同じメッセージを受け取っても悪影響が出ないよう、DynamoDBなどを利用して重複が無いようにする必要があります。
FIFOキュー
「順番配信」、「重複キューの削除」、「一回だけの配信」、「1秒に送信できるキューに制限がある」キューです。
つまり、
(1, 2, 3, 4)->SQS->(1, 2, 3, 4)
となり、DynamoDBなどを利用して重複処理を回避する必要もなくなります!
FIFOキューの制限
SendMessage、ReceiveMessage、DeleteMessageは 300 Message/s
SendMessageBatch、DeleteMessageBatch、ChangeMessageVisibilityBatchを利用すると最大 3000 Message/sとなります。
(SendMessageBatchなどのBatch系では最大10件のメッセージを一つのリクエストで送信することができます)
また、FIFOキューではLambda, SNSなどの連携をサポートしていないため、利用する場合は標準キューを利用する必要があります。
SQSのライフサイクル
SQSには主に「可視性タイムアウト」、「メッセージ保持期間」の設定があります。
可視性タイムアウトは、「コンシューマーがメッセージを受信してから可視性タイムアウトの間、他のコンシューマーなどにキューを配信しない」ものです。
メッセージ保持期間は「SQSにメッセージ保持する期間」で、SQSに登録されてから処理されずにSQSに溜まったメッセージが削除されるまでの期間です。
SQSを使ってアプリケーションを作ってみた
ここまでSQSについて紹介しましたが、実際に使ってみないとよくわからないと思います。
実際にSQSを利用し、「ハンバーガーの注文を受け、厨房で作成する」ものを作ってみたいと思います。
(レジ) ハンバーガーの注文を受け付ける
//@ts-check const AWS = require("aws-sdk"); const SQS = new AWS.SQS({ region: "ap-northeast-1" }) const QueueUrl = "https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/queue"; function order(burger, amount) { const MessageBody = JSON.stringify({ burger, amount }) SQS.sendMessage({ MessageBody, QueueUrl, }, (err, data) => { if (err) return console.error(err, err.stack); console.log(data) }); } order("チーズバーガー", 10);
(厨房) ハンバーガーの注文を処理する
//@ts-check const AWS = require("aws-sdk"); const sqs = new AWS.SQS({ region: "ap-northeast-1" }); const QueueUrl = "https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/queue"; const receiveMessage = QueueUrl => new Promise((resolve, reject) => { const params = { QueueUrl, MaxNumberOfMessages: 10, WaitTimeSeconds: 10 }; sqs.receiveMessage(params, (err, data) => { if (err || !data.Messages) return reject(err); return resolve(data); }); }); const deleteMessage = (ReceiptHandle, QueueUrl) => { const params = { QueueUrl, ReceiptHandle }; sqs.deleteMessage(params, (err, data) => { if (err) return console.error(err); console.log("delete queue"); console.log(data); }); }; const createBurger = burger => new Promise(resolve => { setTimeout(() => resolve("?"), 3000); }); async function main() { while (true) { const data = await receiveMessage(QueueUrl).catch(console.error); if (!data) continue; for (const message of data.Messages) { // ハンバーガーを作る const order = JSON.parse(message.Body); // 重い処理 console.log(order.burger) const result = await createBurger(order.burger); console.log(result) messageids.push(message.MessageId); deleteMessage(message.ReceiptHandle, QueueUrl); } } } main();
標準SQSを利用しているため、実際に利用する場合はDynamoDBを使うなどで受信側で重複を回避する必要があるので、注意が必要です。
まとめ
このように、SQSを利用すると簡単にサービスを分離することができ、AWS側にキューの処理などをまるまる任せられるので、とても便利です!
今回の「AWS再入門ブログリレー」もおかげさまで非常に皆様の高評価を戴いた企画となりました。ご支持戴き誠にありがとうございました!
本リレーを通してAWSのたくさんある様々なサービスに再入門できたなら幸いです!